package data_process

import (
	"fmt"
	"scoce_estimate/config"
	"scoce_estimate/model"
	"scoce_estimate/status"
	"sync"
	"time"
)

var tinfo_queue []*model.Total_score_info

func AddToTQueue(user_id string, level_status int) {
	tinfo_queue = append(tinfo_queue, &model.Total_score_info{User_id: user_id, Level: level_status})
}

func UpdateRank(buffer <-chan *model.Total_score_info, wg *sync.WaitGroup, titles []string, title_map map[string]int) {
	defer wg.Done()
	for {

		tinfo, ok := <-buffer
		fmt.Println("get tinfo, waiting for result： ", tinfo)
		if !ok && tinfo == nil {
			break
		}
		for {
			total := GetTotal(tinfo.User_id, titles, title_map)
			if total >= 0 {
				fmt.Println("total add： ", tinfo)
				AddRanking(tinfo.User_id, total, tinfo.Level)
				break
			} else {
				// 等半秒
				time.Sleep(time.Millisecond * 500)
			}
		}

	}
}

func UpdateData(buffer <-chan *model.Solution, wg *sync.WaitGroup) {
	defer wg.Done()
	for {

		solution, ok := <-buffer
		if !ok && solution == nil {
			break
		}
		for {
			res := GetScore(solution.User_id, solution.Problem_id)
			// fmt.Println(solution)
			if res.Status == status.HAS_RESULT {
				fmt.Println("Solve ", solution.User_id, solution.Problem_id, res.Score)
				break
			} else {
				// 等半秒
				time.Sleep(time.Millisecond * 500)
			}
		}

	}

}

func Total_score_consume(cspj_buffer chan *model.Total_score_info, csps_buffer chan *model.Total_score_info) {
	for {
		if len(tinfo_queue) > 0 {
			item := tinfo_queue[0]
			tinfo_queue = tinfo_queue[1:]
			if item.Level == status.CSPJ_LEVEL {
				cspj_buffer <- item
			} else if item.Level == status.CSPS_LEVEL {
				csps_buffer <- item
			}

			fmt.Println(item, " in")
		} else {
			time.Sleep(time.Second)
		}
	}
}

func Updater(solution_buffer chan *model.Solution, level int, total_buffer chan *model.Total_score_info) {
	var wg sync.WaitGroup
	wg.Add(2)
	go UpdateData(solution_buffer, &wg)
	titles, title_map, _ := config.GetTitleAndMap(level)
	go UpdateRank(total_buffer, &wg, titles, title_map)
	wg.Wait()
}

func GetTotal(user_id string, titles []string, title_map map[string]int) int {
	total := 0
	for i := 0; i < len(titles); i++ {
		problem_id := title_map[titles[i]]
		res := GetScore(user_id, problem_id)
		if res.Status != status.HAS_RESULT {
			return -1
		}
		total += res.Score
	}
	return total
}
